package com.hzit.security.config;

import com.hzit.security.filter.MyFilter;
import com.hzit.security.handler.HzitAccessDeniedHandler;
import com.hzit.security.handler.HzitAuthenticationEntryPoint;
import com.hzit.security.handler.HzitAuthenticationFailureHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.batch.BatchProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import tk.mybatis.spring.annotation.MapperScan;

import javax.sql.DataSource;


/**
 * 类名：
 * 作者：WF
 * 功能： 目前官方建议的做法
 */
@MapperScan("com.hzit.security.mapper")
@Configuration
@EnableGlobalMethodSecurity (securedEnabled = true,prePostEnabled = true)        //  开启授权
public class HzitSecurityConfig2  {
	@Autowired
	private UserDetailsService userDetailsService;
	@Autowired
	private HzitAuthenticationFailureHandler authenticationFailureHandler;
	@Autowired
	private HzitAccessDeniedHandler accessDeniedHandler;
	@Autowired
	private DataSource dataSource;
	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

				http.formLogin()
				.usernameParameter("uname")                     // 修改用户名参数
				.passwordParameter("pwd")                       // 修改密码参数
				.failureHandler(authenticationFailureHandler)   // 认证失败后的处理逻辑
				//.failureUrl("/autherror.html")                // 认证失败后跳转的页面，此时还要放行页面
				.loginPage("/user/login")                       // 登录页面
				.loginProcessingUrl("/login")                   // 登录处理页面
				.and()
				.authorizeRequests()
				// .antMatchers("/webjars/**","/user/login","/autherror.html").permitAll()       // 放行：/webjars/**及/user/login，可以用63行重写的方法代替
				// .anyRequest()
				// .antMatchers("/user/list").hasAuthority("user:userlist")// 代表有user:userlist权限才能访问
				// .antMatchers("/user/list").hasAnyAuthority("user:userlist111","user:touserlist")// 代表有user:userlist111或user:touserlist权限其中一个就能访问
				// .antMatchers("/user/list").hasRole("role:topermissionlist") // 代表有角色role:topermissionlist才能访问资源/user/list
				// .antMatchers("/user/list").hasAnyRole("role:xxxx","role:rolelist.action")	//说明有其中一个角色就可访问资源/user/list
				.anyRequest()
				.authenticated()           // 其它请求必须要经过认证之后才能访问
				.and()
				.csrf().disable();                      // 禁用csrf（请求跨域伪造）
		http.userDetailsService(userDetailsService);    // 指定认证规则
		// 处理授权失败逻辑
		http.exceptionHandling()
				.accessDeniedHandler(accessDeniedHandler);
		// 配置remember-me
		http.rememberMe()
				.userDetailsService(userDetailsService)
				.rememberMeParameter("rememberme")              // 修改“记住我”参数的名字
				.tokenValiditySeconds(24 * 3600)                // cookie的到期时间
				.tokenRepository(persistentTokenRepository());  // 设置关联的数据源
		http.addFilterBefore(new MyFilter(), UsernamePasswordAuthenticationFilter.class);
		return http.build();
	}
	@Bean
	public WebSecurityCustomizer webSecurityCustomizer() {
		return (web) -> web.ignoring().antMatchers("/webjars/**","/user/login","/autherror.html");
	}
	//配置密码加密器
	@Bean
	public PasswordEncoder passwordEncoder(){
		return new BCryptPasswordEncoder();
	}

	@Bean
	public PersistentTokenRepository persistentTokenRepository(){
		JdbcTokenRepositoryImpl persistentTokenRepository = new JdbcTokenRepositoryImpl();
		persistentTokenRepository.setDataSource(dataSource);
		persistentTokenRepository.setCreateTableOnStartup(false) ;  // 启动时自动创建表,第一次运行就改为true
		return persistentTokenRepository;
	}
}
